PostgreSQL: Fix ORDER BY NULL
authorJeff Janes <jeff.janes@gmail.com>
Tue, 8 Jul 2014 20:09:25 +0000 (13:09 -0700)
committerJeff Janes <jeff.janes@gmail.com>
Tue, 8 Jul 2014 20:09:25 +0000 (13:09 -0700)
MySQL automatically orders by the GROUP BY columns if no ORDER BY
is specified.  You can countermand this by specifying
ORDER BY NULL, which can give speed improvements in some cases,
for example if the GROUP BY was implemented by hashing then a
sort is unneeded and wastes time.

PostgreSQL does not tolerate the ORDER BY NULL syntax,
and does not need an analgous hint because it never does
gratuitious sorting of the nature just discussed.

This patch makes PostgreSQL ignore the ORDER BY NULL clause.

It might be a better approach to find a way to add this clause
specifically to MySQL, rather than to drop it specifically from
other database engines.

SQLite seems to tolerate the MySQL syntax.  Oracle and MSSQL
were not evaluated.

Bug: 65794
Change-Id: Ia9666136edd25e1e0d0728a8b28a92e44d00abc6

includes/db/DatabasePostgres.php

index 3d7267a..fe5fa1f 100644 (file)
@@ -827,6 +827,8 @@ __INDEXATTR__;
         * In Postgres when using FOR UPDATE, only the main table and tables that are inner joined
         * can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to do
         * so causes a DB error. This wrapper checks which tables can be locked and adjusts it accordingly.
+        * 
+        * MySQL uses "ORDER BY NULL" as an optimization hint, but that syntax is illegal in PostgreSQL.
         */
        function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__,
                $options = array(), $join_conds = array()
@@ -842,6 +844,10 @@ __INDEXATTR__;
                                        }
                                }
                        }
+
+                       if ( isset( $options['ORDER BY'] ) && $options['ORDER BY'] == 'NULL' ) {
+                               unset( $options['ORDER BY'] );
+                       }
                }
 
                return parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds );